/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Carto;

import Chart.BarChart;
import Chart.ChartFactory;
import Chart.PieChart;
import Chart.PieChart3D;
import Data.SymbolSize;
import intelligenttm.ITMCarto.BaseData;
import intelligenttm.ITMGUIMainController;
import intelligenttm.InPutDlg.AddFenQuDlgController;
import intelligenttm.SVGCarto;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import me.aviator.entity.MBasemap;
import me.aviator.entity.Ribbon;
import me.aviator.entity.Symbol;
import me.aviator.entity.myColor;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.svg.SVGDocument;

/**
 *
 * @author Administrator
 */
public class Carto {
    private SVGCarto svgCarto;
    private int layerId=0;
    public Carto(SVGCarto svg){
        svgCarto=svg;
        NodeList nodes=svgCarto.getSvgDocument().getElementsByTagName("metadata");
        for(int i=0;i<nodes.getLength();i++){
            Element ei=(Element)nodes.item(i);
            String line=ei.getAttribute("id");
            Pattern p=Pattern.compile("[0-9]");
            Matcher matcher=p.matcher(line);
           String strID="";
            while(matcher.find()){
            strID+=matcher.group();
            }
            int id=Integer.parseInt(strID);
            if(id>layerId){
                layerId=id;
            }
        }
    }
    
    public Carto(MBasemap basemap){
        svgCarto=new SVGCarto(basemap);
        NodeList nodes=svgCarto.getSvgDocument().getElementsByTagName("metadata");
        for(int i=0;i<nodes.getLength();i++){
            Element ei=(Element)nodes.item(i);
            String line=ei.getAttribute("id");
            Pattern p=Pattern.compile("[0-9]");
            Matcher matcher=p.matcher(line);
            String strID="";
            while(matcher.find()){
            strID+=matcher.group();
            }
            int id=Integer.parseInt(strID);
            if(id>layerId){
                layerId=id;
            }
        }
    }

    public Carto(){
        
    }
    
    public SVGCarto levelBackground(ArrayList<Integer> range,Ribbon ribbon){
        for(int i=1;i<=range.size();i++){
            if (i < 10) {
                Element root = svgCarto.getSvgDocument().getElementById("Prov_R0" + i);
                setColor(root, ribbon.getColorlist().get(range.get(i-1)-1));
                NodeList nodes=root.getElementsByTagName("path");
                for(int j=0;j<nodes.getLength();j++){
                    Element ei=(Element)nodes.item(j);
                    setColor(ei, ribbon.getColorlist().get(range.get(i-1)-1));
                }
                
            } 
            else {
                Element root = svgCarto.getSvgDocument().getElementById("Prov_R" + i);
                setColor(root, ribbon.getColorlist().get(range.get(i-1)-1));
                NodeList nodes=root.getElementsByTagName("path");
                for(int j=0;j<nodes.getLength();j++){
                    Element ei=(Element)nodes.item(j);
                    setColor(ei, ribbon.getColorlist().get(range.get(i-1)-1));
                }
            }
        }
        return svgCarto;
    }
    private void setColor(Element root,myColor c){ 
	root.setAttribute("style", "fill:#"+String.format("%02x%02x%02x",c.getRed(),c.getGreen(),c.getBlue()));
    }
    
    public SVGCarto drawPieChart3D(List<List<Double>> data,Ribbon ribbon,int count){
        List<Double> sum=new ArrayList<>();
        for(int i=0;i<data.size();i++)
        {
            double sumi=0;
            for(int j=0;j<data.get(i).size();j++)
            {
                sumi+=data.get(i).get(j);
            }
            sum.add(sumi);
        }
        
        SVGDocument doc=svgCarto.getSvgDocument();
        Element root=doc.createElement("g");
        root.setAttribute("id", ("Pie3D-"+count));
        Element meta=doc.createElement("metadata");
        meta.setAttribute("id", "CorelCorpID_"+layerId+"Corel-Layer");
        layerId++;
        root.appendChild(meta);
        
        int k=ribbon.getColorlist().size()-1;
        String color="rgb("+String.format("%d,%d,%d",ribbon.getColorlist().get(k).getRed(),ribbon.getColorlist().get(k).getGreen(),ribbon.getColorlist().get(k).getBlue())+")";
        Element defs=(Element)doc.getElementsByTagName("defs").item(0);
        Element radialG=doc.createElement("radialGradient");
        radialG.setAttribute("id", "colorRadial");
        radialG.setAttribute("cx", "50%");
        radialG.setAttribute("cy", "50%");
        radialG.setAttribute("r", "50%");
        radialG.setAttribute("fx", "50%");
        radialG.setAttribute("fy", "50%");
        Element stop1=doc.createElement("stop");
        stop1.setAttribute("offset", "0%");
        stop1.setAttribute("style", "stop-color:rgb(200,200,200);stop-opacity:0");
        radialG.appendChild(stop1);
        Element stop2=doc.createElement("stop");
        stop2.setAttribute("offset", "100%");
        stop2.setAttribute("style", "stop-color:"+color+";stop-opacity:1");
        radialG.appendChild(stop2);
        defs.appendChild(radialG);
        
        for(int i=1;i<=data.size();i++){
            if(i<10){ 
                Element ei=doc.getElementById("Prov_P0"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                Rectangle2D rect=SymbolSize.getSymbolSize(600, sum.get(i-1), x, y);
                PieChart3D pie=ChartFactory.createPieChart3D(null, null, data.get(i-1), ribbon, rect);
                pie.draw(root, doc);
            }
            else{
                Element ei=doc.getElementById("Prov_P"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                Rectangle2D rect=SymbolSize.getSymbolSize(600, sum.get(i-1), x, y);
                PieChart3D pie=ChartFactory.createPieChart3D(null, null, data.get(i-1), ribbon, rect);
                pie.draw(root, doc);
            }
        }
        svgCarto.getSvgDocument().getDocumentElement().appendChild(root);
        return svgCarto;
    }
    
    public SVGCarto drawPieChart(List<List<Double>> data,Ribbon ribbon,int count){
        List<Double> sum=new ArrayList<>();
        for(int i=0;i<data.size();i++)
        {
            double sumi=0;
            for(int j=0;j<data.get(i).size();j++)
            {
                sumi+=data.get(i).get(j);
            }
            sum.add(sumi);
        }
        
        SVGDocument doc=svgCarto.getSvgDocument();
        Element root=doc.createElement("g");
        root.setAttribute("id", ("Pie-"+count));
        Element meta=doc.createElement("metadata");
        meta.setAttribute("id", "CorelCorpID_"+layerId+"Corel-Layer");
        layerId++;
        root.appendChild(meta);

        for(int i=1;i<=data.size();i++){
            if(i<10){ 
                Element ei=doc.getElementById("Prov_P0"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                Rectangle2D rect=SymbolSize.getSymbolSize(600, sum.get(i-1), x, y);
                PieChart pie=ChartFactory.createPieChart(null, null, data.get(i-1), ribbon, rect);
                pie.draw(root, doc);
            }
            else{
                Element ei=doc.getElementById("Prov_P"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                Rectangle2D rect=SymbolSize.getSymbolSize(600, sum.get(i-1), x, y);
                PieChart pie=ChartFactory.createPieChart(null, null, data.get(i-1), ribbon, rect);
                pie.draw(root, doc);
            }
        }
        svgCarto.getSvgDocument().getDocumentElement().appendChild(root);
        return svgCarto;
    }
    
    public SVGCarto drawArtSymbol(List<Double> data,Symbol s,int count){
        InputStream is = new ByteArrayInputStream(s.getSvgxml()); 
        String parser = XMLResourceDescriptor.getXMLParserClassName();
        SAXSVGDocumentFactory SAXSVGDF = new SAXSVGDocumentFactory(parser);
        Document sdoc=null;
        try {
            sdoc = SAXSVGDF.createDocument(null,is);
        } catch (IOException ex) {
            Logger.getLogger(ITMGUIMainController.class.getName()).log(Level.SEVERE, null, ex);
        }
        SVGDocument doc=svgCarto.getSvgDocument();
        SVGDocument sDoc=(SVGDocument)sdoc;
        String symbolID = copyElement(doc,sDoc);

        double Yoffset=0;
        String viewBoxY=doc.getRootElement().getAttribute("viewBox");
        if(viewBoxY!=null)
        {
            viewBoxY=(viewBoxY.split(" "))[3];
            Yoffset=Double.parseDouble(viewBoxY);
        }
        Element root=doc.createElement("g");
        root.setAttribute("id", ("ArtSymbol-"+count));
        Element meta=doc.createElement("metadata");
        meta.setAttribute("id", "CorelCorpID_"+layerId+"Corel-Layer");
        layerId++;
        root.appendChild(meta);
//        root.appendChild(symbol1);

        for(int i=1;i<=data.size();i++){
            if(i<10){ 
                Element ei=doc.getElementById("Prov_P0"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                Rectangle2D rect=SymbolSize.getSymbolSize(600, data.get(i-1), x, y);
                Element art=doc.createElement("use");
                art.setAttribute("x", ""+x);
                art.setAttribute("y", ""+(y-Yoffset/2.0));
                art.setAttribute("width", ""+rect.getWidth());
                art.setAttribute("hight",""+rect.getHeight());
                art.setAttribute("xlink:href", "#"+symbolID);
                root.appendChild(art);
            }
            else{
                Element ei=doc.getElementById("Prov_P"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                Rectangle2D rect=SymbolSize.getSymbolSize(600, data.get(i-1), x, y);
                Element art=doc.createElement("use");
                art.setAttribute("x", ""+x);
                art.setAttribute("y", ""+(y-Yoffset/2.0));
                art.setAttribute("width", ""+rect.getWidth());
                art.setAttribute("hight",""+rect.getHeight());
                art.setAttribute("xlink:href", "#"+symbolID);
                root.appendChild(art);
            }
        }
        svgCarto.getSvgDocument().getDocumentElement().appendChild(root);
        return svgCarto;
    }
    
    private String copyElement(SVGDocument doc,SVGDocument sDoc)
    {////先拷贝defs，后拷贝symbol
        String symbolID="";
        Node Sdefs=sDoc.getElementsByTagName("defs").item(0);
        if(Sdefs!=null)
        {
        Node Ddefs=doc.getElementsByTagName("defs").item(0);
        if(Ddefs==null)
        {
            Ddefs=doc.createElement("defs");
            doc.getRootElement().appendChild(Ddefs);
        }
        NodeList Snodes=Sdefs.getChildNodes();
        for(int i=0;i<Snodes.getLength();i++){
            if(!Snodes.item(i).hasAttributes()) continue;
            Element Se=(Element)Snodes.item(i);
            switch(Snodes.item(i).getNodeName()){
                case "radialGradient":
                    Element rgEl=doc.createElement("radialGradient");
                    rgEl.setAttribute("id", Se.getAttribute("id"));
                    rgEl.setAttribute("gradientUnits", Se.getAttribute("gradientUnits"));
                    rgEl.setAttribute("cx", Se.getAttribute("cx"));
                    rgEl.setAttribute("cy", Se.getAttribute("cy"));
                    rgEl.setAttribute("r", Se.getAttribute("r"));
                    rgEl.setAttribute("fx", Se.getAttribute("fx"));
                    rgEl.setAttribute("fy", Se.getAttribute("fy"));
                    NodeList rgNodes=Se.getChildNodes();
                    for(int j=0;j<rgNodes.getLength();j++){
                        if(rgNodes.item(j).hasAttributes())
                        {
                        Element Sstop=(Element)rgNodes.item(j);
                        Element Dstop=doc.createElement("stop");
                        Dstop.setAttribute("offset", Sstop.getAttribute("offset"));
                        Dstop.setAttribute("stop-color", Sstop.getAttribute("stop-color"));
                        rgEl.appendChild(Dstop);
                        }
                    }
                    Ddefs.appendChild(rgEl);
                    break;
                default:
                    break;
            }
        }
        }
        Node Ssymbol=sDoc.getElementsByTagName("symbol").item(0);
        Element symbol=doc.createElement("symbol");
        symbolID=((Element)Ssymbol).getAttribute("id");
        symbol.setAttribute("id", ((Element)Ssymbol).getAttribute("id"));
        symbol.setAttribute("preserveAspectRatio", "xMidYMid meet");
        symbol.setAttribute("viewBox",((Element)Ssymbol).getAttribute("viewBox"));
        NodeList Spath=Ssymbol.getChildNodes();
        for(int i=0;i<Spath.getLength();i++){
            if(Spath.item(i).hasAttributes())
            {
                Element ss=(Element)Spath.item(i);
                Element path1=doc.createElement(ss.getNodeName());
                path1.setAttribute("fill", ss.getAttribute("fill"));
                if(ss.getAttribute("stroke")!=null)
                {
                path1.setAttribute("stroke", ss.getAttribute("stroke"));
                }
                if(ss.getAttribute("stroke-width")!=null)
                {
                path1.setAttribute("stroke-width", ss.getAttribute("stroke-width"));
                }
                path1.setAttribute("d", ss.getAttribute("d"));
                symbol.appendChild(path1);
            }
        }
        doc.getRootElement().appendChild(symbol);
        return symbolID;
    }
    
    public SVGCarto drawBarChart(List<List<Double>> data,Ribbon ribbon,int count)
    {
        SVGDocument doc=svgCarto.getSvgDocument();
        Element root=doc.createElement("g");
        root.setAttribute("id", ("Bar-"+count));
        Element meta=doc.createElement("metadata");
        meta.setAttribute("id", "CorelCorpID_"+layerId+"Corel-Layer");
        layerId++;
        root.appendChild(meta);

        for(int i=1;i<=data.size();i++){
            if(i<10){ 
                Element ei=doc.getElementById("Prov_P0"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                BarChart bar=ChartFactory.createBarChart(null, null, data.get(i-1), ribbon, x, y, 2600);
                bar.draw(root, doc);
            }
            else{
                Element ei=doc.getElementById("Prov_P"+i);
                double x=Double.parseDouble(ei.getAttribute("cx"));
                double y=Double.parseDouble(ei.getAttribute("cy"));
                BarChart bar=ChartFactory.createBarChart(null, null, data.get(i-1), ribbon, x, y, 2600);
                bar.draw(root, doc);
            }
        }
        svgCarto.getSvgDocument().getDocumentElement().appendChild(root);
        return svgCarto;
    }
    
    public Ribbon getFenJiRibbon() {
        return svgCarto.getFenJiRibbon();
    }

    public void setFenJiRibbon(Ribbon FenJiRibbon) {
        svgCarto.setFenJiRibbon(FenJiRibbon);
    }

    public String getFenJiAttribute() {
        return svgCarto.getFenJiAttribute();
    }

    public void setFenJiAttribute(String FenJiAttribute) {
        svgCarto.setFenJiAttribute(FenJiAttribute);
    }
    
    
    public void addAttributeList(List Attribute){
        svgCarto.addAttributeList(Attribute);
    }
    public void addSymbolLayerList(AddFenQuDlgController SymbolList){
        svgCarto.addSymbolLayerList(SymbolList);
    }
    
    public void setAttributeList(List NewAttributeList){
        svgCarto.setAttributeList(NewAttributeList);
    }
    public void setSymbolLayerList(List NewSymbolLayerList){
        svgCarto.setSymbolLayerList(NewSymbolLayerList);
    }
    
    public List<BaseData> getBDList() {
        return svgCarto.getBDList();
    }

    public void setBDList(List<BaseData> BDList) {
        svgCarto.setBDList(BDList);
    }
    
    public void addSymbolIDList(String ID){
        svgCarto.addSymbolIDList(ID);
    }
    
    public List<String> getSymbolIDList() {
        return svgCarto.getSymbolIDList();
    }

    public void setSymbolIDList(List<String> SymbolIDList) {
        svgCarto.setSymbolIDList(SymbolIDList);
    }
    
}
